//
//  XinLvTestingViewController.m
//  安好
//
//  Created by qinlongqing on 14-9-1.
//  Copyright (c) 2014年 冯凯. All rights reserved.
//

#import "XinLvTestingViewController.h"
#import "WaveformGraphViewController.h"
#import "XinLvTestViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "AppConfig.h"

@interface XinLvTestingViewController ()<AVCaptureVideoDataOutputSampleBufferDelegate,UIAlertViewDelegate>
{
    NSTimer *timer;
    
    NSMutableDictionary *numberForDataDict;
    
    WaveformGraphViewController *waveformGraphViewController;
    
    AVCaptureSession *session;
    
    NSMutableArray *testResultNumbers;//所有的测试结果
    NSMutableArray *testSamples;//每秒钟抽样一次的结果
    
    NSInteger currentTime;
    BOOL isTesting;//标记是否开始测试
}
@end

@implementation XinLvTestingViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.navigationItem.title = @"心率";
    [self.view setBackgroundColor:UIColorFromRGB(0x4fc1e9)];
    
    [self makeNavBar];
    
    currentTime = 1;
    isTesting = NO;
    
    [self initData];
    
    [self showNumber:000];
    
    [self setupAVCapture];
}

- (void)makeNavBar{
    UIBarButtonItem *backBtnImg = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"公用_返回.png"] style:UIBarButtonItemStylePlain target:self action:@selector(doBack)];
    [backBtnImg setTintColor:[UIColor whiteColor]];
    self.navigationItem.leftBarButtonItem = backBtnImg;
}

-(void)doBack{
    //    [timer invalidate];
    //
    //    [self stopAVCapture];
    //
    //    [waveformGraphViewController removeWaveformViewTimer];
    [self stopTimerAndRemoveWaveformGraphView];
    
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)initData{
    numberForDataDict = [[NSMutableDictionary alloc]init];
    for (int i=0; i<=9; i++) {
        switch (i) {
            case 0:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@6,@8,@12,@14,@16,@20,@19,@18,@17,@15,@13,@9,@7,@5] forKey:@"0"];
            case 1:
                [numberForDataDict setObject:@[@4,@6,@8,@12,@14,@16,@20] forKey:@"1"];
                break;
            case 2:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@6,@8,@12,@11,@10,@9,@13,@15,@17,@18,@19,@20] forKey:@"2"];
                break;
            case 3:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@6,@8,@12,@11,@10,@9,@14,@16,@20,@19,@18,@17] forKey:@"3"];
                break;
            case 4:
                [numberForDataDict setObject:@[@1,@5,@7,@9,@10,@11,@12,@4,@6,@8,@14,@16,@20] forKey:@"4"];
                break;
            case 5:
                [numberForDataDict setObject:@[@4,@3,@2,@1,@5,@7,@9,@10,@11,@12,@14,@16,@20,@19,@18,@17] forKey:@"5"];
                break;
            case 6:
                [numberForDataDict setObject:@[@4,@3,@2,@1,@5,@7,@9,@13,@15,@17,@18,@19,@20,@16,@14,@12,@11,@10] forKey:@"6"];
                break;
            case 7:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@6,@8,@12,@14,@16,@20] forKey:@"7"];
                break;
            case 8:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10,@11,@12,@13,@14,@15,@16,@17,@18,@19,@20] forKey:@"8"];
                break;
            case 9:
                [numberForDataDict setObject:@[@1,@2,@3,@4,@6,@8,@12,@14,@16,@20,@11,@10,@9,@7,@5] forKey:@"9"];
                break;
                
            default:
                break;
        }
    }
}

- (void)doDaoJiShi{
    if (currentTime <= 30) {
        if (currentTime > 20) {
            self.daoJiShiLabel.text = [NSString stringWithFormat:@"00:0%ld",30 - currentTime];
        }
        else{
            self.daoJiShiLabel.text = [NSString stringWithFormat:@"00:%ld",30-currentTime];
        }
//        CGFloat width = self.progressBGImageView.frame.size.width;
//        
//        CGRect rect = self.progressImageView.frame;
//        rect.size.width = currentTime/60.0 * width;
//        self.progressImageView.frame = rect;
//        
//        MyNSLog("***********x=%f  y=%f width=%f height=%f",self.progressImageView.frame.origin.x,self.progressImageView.frame.origin.y,self.progressImageView.frame.size.width,self.progressImageView.frame.size.height);
        
        currentTime++;
        if (currentTime == 31) {
            MyNSLog("销毁了倒计时");
            [timer invalidate];
        }

        
        [self sampleAnTestResult];
        
        
    }
    if (currentTime == 31) {
        //计算出心率平均值
        if (testSamples.count > 0) {
            NSMutableArray *finalTestResultArray = [[NSMutableArray alloc]init];
            [testSamples enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                if ([obj integerValue] != 0) {
                    [finalTestResultArray addObject:obj];
                }
            }];
            if (finalTestResultArray.count >= 3) {
                for (int i= 0; i<finalTestResultArray.count - 1; i++) {
                    for (int j=0; j<finalTestResultArray.count -1 - i; j++) {
                        if ([[finalTestResultArray objectAtIndex:j] integerValue] > [[finalTestResultArray objectAtIndex:j + 1] integerValue]) {
                            [finalTestResultArray exchangeObjectAtIndex:j withObjectAtIndex:j+1];
                        }
                    }
                }
                NSInteger total = 0;
                for (int k=1; k<finalTestResultArray.count - 1; k++) {
                    total += [[finalTestResultArray objectAtIndex:k] integerValue];
                }
                [self.xinLvTestViewController xinLvTestFinishedWithResult:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:(total/(finalTestResultArray.count - 2))],kXinLvTestResult, nil]];
            }
            else{
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"测试失败"] message:@"请把手放到指定位置后重试!" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil];
                [alertView show];
            }
        }
        else{
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"测试失败"] message:@"请把手放到指定位置后重试!" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil];
            [alertView show];
        }
        
        [self stopTimerAndRemoveWaveformGraphView];
    }
}

- (void)sampleAnTestResult{//抽样
    if (testResultNumbers.count > 0) {
        [testSamples addObject:[testResultNumbers lastObject]];
        [self showNumber:[[testSamples lastObject] integerValue]];
    }
}

- (void)showNumber:(int)number inView:(UIView *)anView{
    NSArray *numberData = [numberForDataDict valueForKey:[NSString stringWithFormat:@"%d",number]];
    
    for (int i=1; i<=20; i++) {
        UIImageView *imageView = (UIImageView *)[anView viewWithTag:i];
        imageView.image = [UIImage imageNamed:@"xin_lv_number_no"];
    }
    
    for (int i=0; i<numberData.count; i++) {
        UIImageView *imageView = (UIImageView *)[anView viewWithTag:[[numberData objectAtIndex:i] integerValue]];
        imageView.image = [UIImage imageNamed:@"xin_lv_number_yes"];
    }
}

- (void)showNumber:(int)theNumber{
    if (theNumber/1000) {
        return;
    }
    int bai = theNumber/100;
    int currentNumber = theNumber%100;
    
    int shi = currentNumber/10;
    int ge = currentNumber%10;
    
    [self showNumber:bai inView:self.showNumberView1];
    [self showNumber:shi inView:self.showNumberView2];
    [self showNumber:ge inView:self.showNumberView3];
    
    [waveformGraphViewController addPointToDataSource:theNumber];
}

#pragma 波形图实现
- (void)addWaveformGraph{
    waveformGraphViewController = [[WaveformGraphViewController alloc]init];
    waveformGraphViewController.waveformGraphViewRect = self.xinLvCurveBGImageView.frame;
    [waveformGraphViewController initData];
    
    [self.view addSubview:(UIView *)[waveformGraphViewController getTranslationMoniterView]];
}

- (void)startProgressAnimation{
    [UIView animateWithDuration:30 animations:^{
        self.progressImageView.frame = self.progressBGImageView.frame;
    }];
}

- (void)setupAVCapture{
    // Get the default camera device
    testResultNumbers = [[NSMutableArray alloc]init];
    testSamples = [[NSMutableArray alloc]init];
    
	AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
	if([device isTorchModeSupported:AVCaptureTorchModeOn]) {
//
//        AVFrameRateRange *bestFrameRateRange = nil;
//        AVCaptureDeviceFormat *bestFormat = nil;
//        
//        for ( AVCaptureDeviceFormat *format in [device formats] ) {
//            for ( AVFrameRateRange *range in format.videoSupportedFrameRateRanges ) {
//                if ( range.maxFrameRate > bestFrameRateRange.maxFrameRate ) {
//                    bestFormat = format;
//                    bestFrameRateRange = range;
//                }
//            }
//        }
//        if ( bestFormat ) {
//            if ( [device lockForConfiguration:NULL] == YES ) {
//                device.activeFormat = bestFormat;
//                device.activeVideoMinFrameDuration = bestFrameRateRange.minFrameDuration;
//                device.activeVideoMaxFrameDuration = bestFrameRateRange.minFrameDuration;
//                [device unlockForConfiguration];
//            }
//        }
//
		[device lockForConfiguration:nil];
		device.torchMode=AVCaptureTorchModeOn;
        [device setTorchMode:AVCaptureTorchModeOn];
		[device unlockForConfiguration];
	}
	// Create the AVCapture Session
	session = [AVCaptureSession new];
    [session beginConfiguration];
	// Create a AVCaptureDeviceInput with the camera device
	NSError *error = nil;
	AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
	if (error) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"提示"] message:@"无法打开摄像头" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil];
        [alertView show];
        //[self teardownAVCapture];
        return;
    }
    if ([session canAddInput:deviceInput]){
		[session addInput:deviceInput];
    }
    // AVCaptureVideoDataOutput
    AVCaptureVideoDataOutput *videoDataOutput = [AVCaptureVideoDataOutput new];
	NSDictionary *rgbOutputSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
	[videoDataOutput setVideoSettings:rgbOutputSettings];
	[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];
	dispatch_queue_t videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
	[videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
    
    if ([session canAddOutput:videoDataOutput]){
		[session addOutput:videoDataOutput];
    }
    AVCaptureConnection* connection = [videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
    if ([connection respondsToSelector:@selector(setVideoMinFrameDuration:)]) {
        [connection setVideoMinFrameDuration:CMTimeMake(1, 10)];
    }
    [connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
    
    [session commitConfiguration];
    [session startRunning];
}

- (void)stopAVCapture{
    [session stopRunning];
    session = nil;
}

#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
    uint8_t *buf = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,bytesPerRow, colorSpace,kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    
    float r = 0, g = 0,b = 0;
	for(int y = 0; y < height; y++) {
		for(int x = 0; x < width * 4; x += 4) {
			b += buf[x];
			g += buf[x+1];
			r += buf[x+2];
		}
		buf += bytesPerRow;
	}
	r /= 255 * (float)(width * height);
	g /= 255 * (float)(width * height);
	b /= 255 * (float)(width * height);
    
	float h,s,v;
	RGBtoHSV(r, g, b, &h, &s, &v);
	static float lastH = 0;
	float highPassValue = h - lastH;
	lastH = h;
    float lastHighPassValue = 0;
    
    if ([AppConfig currentDeviceString] == iPhone_4 || [AppConfig currentDeviceString] == iPhone_4S) {
        float lowPassValue = (lastHighPassValue + highPassValue) / 2;
        lastHighPassValue = highPassValue;

        NSInteger yPOS = 154 / 2 + lowPassValue * 154 / 2 - 35;

//        MyNSLog("****4/4s****0000**** h=%f  yPOS = %d",h,yPOS);
        
        if ((h >= 2 && h <= 17)) {// || (h > 0 && h < 5)
            if (isTesting == 0) {
                isTesting = 1;
                
                [self performSelectorOnMainThread:@selector(startProgressAnimation) withObject:nil waitUntilDone:NO];
                
                [self performSelectorOnMainThread:@selector(addWaveformGraph) withObject:nil waitUntilDone:YES];
                
                timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(doDaoJiShi) userInfo:nil repeats:YES];
                [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
                
            }
            
//            MyNSLog("~~~~4/4s~~~~~1111~~~~ h=%f  yPOS = %d",h,yPOS);
            
            if (yPOS >= 160 || yPOS <= 40) {
                [testResultNumbers addObject:[NSNumber numberWithInteger:60]];
            }
            else{
                [testResultNumbers addObject:[NSNumber numberWithInteger:yPOS]];
            }
        }
        else{
//            MyNSLog("*****4/4s*****2222**** h=%f  yPOS = 0",h);
            
            [testResultNumbers addObject:[NSNumber numberWithInteger:0]];
        }
    }
    else{
        float lowPassValue = (lastHighPassValue + highPassValue) / 2;
        lastHighPassValue = highPassValue;

        NSInteger yPOS = 154 / 2 + lowPassValue * 154 / 2 - 15;

        MyNSLog("****5/5s****0000**** h=%f  yPOS = %d",h,yPOS);
        
        if ((h >= 345 && h <= 360)) {// || (h > 0 && h < 5)
            if (isTesting == 0) {
                isTesting = 1;
                
                [self performSelectorOnMainThread:@selector(startProgressAnimation) withObject:nil waitUntilDone:NO];
                
                [self performSelectorOnMainThread:@selector(addWaveformGraph) withObject:nil waitUntilDone:YES];
                
                timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(doDaoJiShi) userInfo:nil repeats:YES];
                [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
                
            }
            
//            MyNSLog("~~~~5/5s~~~~~1111~~~~ h=%f  yPOS = %d",h,yPOS);
            
            if (yPOS >= 160 || yPOS <= 40) {
                [testResultNumbers addObject:[NSNumber numberWithInteger:60]];
            }
            else{
                [testResultNumbers addObject:[NSNumber numberWithInteger:yPOS]];
            }
        }
        else{
//            MyNSLog("****5/5s****2222**** h=%f  yPOS = 0",h);
            
            [testResultNumbers addObject:[NSNumber numberWithInteger:0]];
        }
    }
    
    
//    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];//实例化一个NSDateFormatter对象
//    [dateFormat setLocale:[NSLocale currentLocale]];
//    [dateFormat setDateFormat:@"yyyyMMddHHmmssSSS"];
//    NSString *dateString = [dateFormat stringFromDate:[NSDate date]];//再从字符串转成指定格式的字符串
    
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
}

void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v ) {
	float min, max, delta;
	min = MIN( r, MIN(g, b ));
	max = MAX( r, MAX(g, b ));
	*v = max;
	delta = max - min;
	if( max != 0 )
		*s = delta / max;
	else {
		*s = 0;
		*h = -1;
		return;
	}
	if( r == max )
		*h = ( g - b ) / delta;
	else if( g == max )
		*h = 2 + (b - r) / delta;
	else
		*h = 4 + (r - g) / delta;
	*h *= 60;
	if( *h < 0 )
		*h += 360;
}

- (void)stopTimerAndRemoveWaveformGraphView{
    if ([timer isValid]) {
        [timer invalidate];
    }
    
    [self stopAVCapture];
    
    [waveformGraphViewController removeWaveformViewTimer];
}

- (void)dealloc{
    MyNSLog("xin lv testing view controller dealloc");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
